<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Event</title>
    <link rel="stylesheet" href="http://yui.yahooapis.com/3.4.0pr3/build/cssgrids/grids-min.css">
    <link rel="stylesheet" href="../assets/css/main.css">
    <link rel="stylesheet" href="../assets/vendor/prettify/prettify-min.css">
    <script src="../../build/yui/yui-min.js"></script>
</head>
<body>

<div id="doc">
    <h1>Event</h1>

    
        <a href="#toc" class="jump">Jump to Table of Contents</a>
    

    <div class="yui3-g">
        <div id="main" class="yui3-u">
            <div class="content"><style>
    h4 code {
        text-transform: none;
    }
    .yui3-skin-sam td {
        background-color: #E6E9F5;
    }
    .yui3-skin-sam .yui3-datatable td {
        background-color: transparent;
    }
</style>

<div class="intro component">
    <p>The YUI Event Utility provides APIs for working with the browser's DOM
    event system.  It simplifies tasks like subscribing to button <code>click</code>s or
    canceling &lt;form&gt; <code>submit</code>s to, for example, allow sending data to the
    server via ajax.</p>
    
    <p>In addition, the "Synthetic event" system supplies <em>entirely new</em>
    DOM events to subscribe to as well as fixing events that behave differently
    across browsers.  Implementers can create their own DOM events triggered by
    specific user actions or other environmental criteria.</p>

    <p>The API for working with DOM events is provided by the EventTarget class,
    which also services the Custom event infrastructure that is used throughout
    YUI.  Read more about working with custom events <a
    href="../event-custom/index.html">in the EventTarget user guide</a>.</p>
</div>

<h2 id="getting-started">Getting Started</h2>

<p>
To include the source files for Event and its dependencies, first load
the YUI seed file if you haven't already loaded it.
</p>

<pre class="code prettyprint">&lt;script src=&quot;http:&#x2F;&#x2F;yui.yahooapis.com&#x2F;3.4.0&#x2F;build&#x2F;yui&#x2F;yui-min.js&quot;&gt;&lt;&#x2F;script&gt;</pre>


<p>
Next, create a new YUI instance for your application and populate it with the
modules you need by specifying them as arguments to the <code>YUI().use()</code> method.
YUI will automatically load any dependencies required by the modules you
specify.
</p>

<pre class="code prettyprint">&#x2F;&#x2F; Create a new YUI instance and populate it with the required modules.
YUI().use(&#x27;event&#x27;, function (Y) {
    &#x2F;&#x2F; Event is available and ready for use. Add implementation
    &#x2F;&#x2F; code here.
});</pre>


<p>
For more information on creating YUI instances and on the
<a href="http://yuilibrary.com/yui/docs/api/classes/YUI.html#method_use"><code>use()</code> method</a>, see the
documentation for the <a href="../yui/index.html">YUI Global object</a>.
</p>


<h2 id="the-basics">The Basics</h2>

<h4 id="listening-for-events">Listening for events</h4>
<pre class="code prettyprint">&#x2F;&#x2F; Step 1. Capture a button node
var button = Y.one(&quot;#readygo&quot;);

&#x2F;&#x2F; Step 2. Subscribe to its click event with a callback function
button.on(&quot;click&quot;, function (e) {

    &#x2F;&#x2F; Step 3. do stuff when the button is clicked

});</pre>


<p><code>on(<em>type</em>, <em>callback</em>)</code> is the main 
subscription method, and is available on every <a href="../node/"><code>Node</code></a>
and <a href="../node/#nodelist"><code>NodeList</code></a>.</p>

<p>Replace "click" with <a href="#event-whitelist">any other event name</a> to subscribe to that event.</p>

<h4 id="the-callback-and-the-event-object">The Callback and the Event Object</h4>

<pre class="code prettyprint">button.on(&#x27;click&#x27;, function (e) {
    &#x2F;&#x2F; &#x60;this&#x60; is the button Node, NOT the DOM element
    this.get(&#x27;id&#x27;); &#x2F;&#x2F; ==&gt; &#x27;readygo&#x27; (from &lt;button id=&quot;readygo&quot;&gt;...&lt;&#x2F;button&gt;)

    &#x2F;&#x2F; Event properties that point to the DOM are also Node instances
    e.target.get(&#x27;id&#x27;); &#x2F;&#x2F; =&gt; &#x27;readygo&#x27;
    
    &#x2F;&#x2F; Stop the event&#x27;s default behavior
    e.preventDefault();

    &#x2F;&#x2F; Stop the event from bubbling up the DOM tree
    e.stopPropagation();
});</pre>


<p>Subscribed callbacks are passed a <a href="#facade-properties">a normalized
event object</a> as their first argument.</p>

<p>The keyword "<code>this</code>" in the callback will refer to the Node or NodeList
that you subscribed from.</p>

<h4 id="epreventdefault-and-estoppropagation"><code>e.preventDefault()</code> and <code>e.stopPropagation()</code></h4>

<p>Many events have a default behavior, such as the <code>submit</code> event serializing
form data and making a new page request.  Disable this behavior with
<code>e.preventDefault()</code>.</p>

<pre class="code prettyprint">function setFilter(e) {
    &#x2F;&#x2F; Stop the link from loading the href page
    e.preventDefault();

    &#x2F;&#x2F; Now do my own thing instead
    var url = this.get(&#x27;href&#x27;).replace(&#x2F;page&#x2F;, &#x27;partial&#x27;);

    Y.one(&#x27;#contentArea&#x27;).load(url);

    &#x2F;&#x2F; &#x60;return false&#x60; is supported, but not preferred. use e.preventDefault()
    return false;
}

Y.one(&#x27;#table-filter-link&#x27;).on(&#x27;click&#x27;, setFilter);</pre>


<p>Most events can be listened for on the specific element that originates them
<em>or from any of their parent elements</em>, all the way up to the
<code>document</code>.  Prevent dispatching the event to subscriptions bound to elements
further up the DOM tree with <code>e.stopPropagation()</code>.  In practice, this is
rarely useful.</p>

<p>Returning <code>false</code> from a callback will also stop the propagation of the
event, which may cause unintended side effects.</p>

<p><code>e.stopPropagation()</code> won't prevent the execution of other subscribers
listening to the same element, only elements further up the DOM tree.  If you
need to stop all execution, use <code>e.stopImmediatePropagation()</code> or
<code>e.halt(true)</code>. The latter will also call <code>e.preventDefault()</code>.</p>

<h4 id="detaching-subscriptions">Detaching subscriptions</h4>

<p><code>node.on()</code> and all
<a href="#more">other subscription methods</a> return a
subscription object that can be used to unbind that subscription.  Node also
supports a <code>detach()</code> method and <a href="#detach-methods">other ways to cleaup
subscriptions</a>.</p>

<pre class="code prettyprint">&#x2F;&#x2F; on() returns a subscription handle...
var sub = button.on(&quot;click&quot;, handleClick);

&#x2F;&#x2F; ...that can be used to unbind the subscription
sub.detach();

&#x2F;&#x2F; Alternately, use the Node&#x27;s detach() method
button.detach(&quot;click&quot;, handleClick);</pre>


<p>Just this should take care of most of the simple event bindings you'll need.
There's <a href="#more">a lot more you can do</a>, though, so read on!</p>

<h2 id="modules">What to <code>use()</code></h2>

<p>
    Before we get into <a href="#more">more API goodies</a>, let's talk about
    the Event Utility's module breakdown.
</p>

<p>
    For starters, in most cases <em>you probably won't <code>use(&#x27;event&#x27;)</code></em>.
    The core DOM event system ("event-base") is required by the "node-base"
    module, which itself if required by just about everything in YUI.  So you
    probably already have the DOM event API and didn't know it!
</p>

<p>Here is the full breakdown of modules in the DOM event system:</p>

<table>
<thead>
    <tr>
        <th><code>use(&quot;______&quot;, ...)</code></th>
        <th>What's in it?</th>
    </tr>
</thead>
<tbody>
    <tr>
        <td><a href="http://yuilibrary.com/yui/docs/api/module_event-base.html"><code>event-base</code></a></td>
        <td>
            <p>
                The core DOM event subscription system as well as the DOM
                lifecycle events <a href="domready.html"><code>domready</code>,
                <code>contentready</code>, and <code>available</code></a>.  Notably, it does NOT
                include
            </p>
            <ul>
                <li>event delegation</li>
                <li>event simulation</li>
                <li>synthetic events</li>
            </ul>

            <p>If you've <code>use()</code>d anything, you probably have this already.</p>
        </td>
    </tr>
    <tr>
        <td><a href="http://yuilibrary.com/yui/docs/api/module_event.html"><code>event</code></a></td>
        <td>
            A rollup of all modules below except
            <ul>
                <li>"event-simulate"</li>
                <li>"node-event-simulate"</li>
                <li>"node-event-delegate" (which is in the "node" rollup)</li>
            </ul>
        </td>
    </tr>
    <tr>
        <td><a href="http://yuilibrary.com/yui/docs/api/module_event-delegate.html"><code>event-delegate</code></a> &amp;
            <br>
            <a style="white-space: nowrap;" href="http://yuilibrary.com/yui/docs/api/module_node-event-delegate.html"><code>node-event-delegate</code></a></td>
        <td>
            Adds the <code>Y.delegate(...)</code> and <code>node.delegate(...)</code> methods,
            respectively, for <a href="#delegation">event delegation</a>
            convenience.
        </td>
    </tr>
    <tr>
        <td><a href="http://yuilibrary.com/yui/docs/api/module_event-simulate.html"><code>event-simulate</code></a> &amp;
            <br>
            <a style="white-space: nowrap;" href="http://yuilibrary.com/yui/docs/api/module_node-event-simulate.html"><code>node-event-simulate</code></a></td>
        </td>
        <td>
            <p>
                Adds <code>Y.Event.simulate(...)</code> and <code>node.simulate(...)</code> for
                <a href="#simulate">triggering native DOM events</a> for
                unit testing.
            </p>
            <p>
                <strong>Note: <a href="simulate.html#faking">Faking DOM events
                should not be used in user facing code</a></strong>.
            </p>
        </td>
    </tr>
    <tr>
        <td><a href="http://yuilibrary.com/yui/docs/api/module_event-synthetic.html"><code>event-synthetic</code></a></td>
        <td>
            <p>Supplies the infrastructure for creating new DOM events, "fixing"
            existing events with undesirable or inconsistent behavior, and
            <a href="synths.html">all sorts of other things</a>.</p>
            
            <p>All of the modules below are synthetics.</p>
        </td>
    </tr>
    <tr>
        <td><a href="http://yuilibrary.com/yui/docs/api/module_event-flick.html"><code>event-flick</code></a></td>
        <td>
            Adds a <a href="touch.html#flick">"flick" event</a> for touch or
            mouse interaction.
        </td>
    </tr>
    <tr>
        <td><a href="http://yuilibrary.com/yui/docs/api/module_event-focus.html"><code>event-focus</code></a></td>
        <td>
            <a href="focus.html">Fixes <code>focus</code> and <code>blur</code> events</a> to bubble
            (for delegation).
        </td>
    </tr>
        <td><a href="http://yuilibrary.com/yui/docs/api/module_event-gestures.html"><code>event-gestures</code></a></td>
        <td>
            <p>A rollup of the following modules:</p>

            <ul>
                <li>"event-touch"</li>
                <li>"event-move"</li>
                <li>"event-flick"</li>
            </ul>

            <p>In the future, may contain more gesture abstraction modules.</p>
        </td>
    <tr>
        <td><a href="http://yuilibrary.com/yui/docs/api/module_event-hover.html"><code>event-hover</code></a></td>
        <td>
            Adds a <a href="mouseenter.html#hover">"hover" event</a> which
            binds to two callbacks, one for the start, and one for the end of a
            mouse hover.
        </td>
    </tr>
    <tr>
        <td><a href="http://yuilibrary.com/yui/docs/api/module_event-key.html"><code>event-key</code></a></td>
        <td>
            Adds a <a href="key.html">"key" event</a> which listens for
            specific, implementer defined, keys being pressed by the user.
        </td>
    </tr>
    <tr>
        <td><a href="http://yuilibrary.com/yui/docs/api/module_event-mouseenter.html"><code>event-mouseenter</code></a></td>
        <td>
            Adds <a href="mouseenter.html">"mouseenter" and "mouseleave"
            events</a>.  You probably want to use these instead of "mouseover"
            and "mouseout".
        </td>
    </tr>
    <tr>
        <td><a href="http://yuilibrary.com/yui/docs/api/module_event-mousewheel.html"><code>event-mousewheel</code></a></td>
        <td>
            <p>Adds a "mousewheel" event for monitoring users scrolling the
            window with the mousewheel.  Event facades passed to the callback
            will have an <code>e.wheelDelta</code> property corresponding to the amount of
            scrolling.</p>

            <p>Currently, this event can only be subscribed with
            <code>Y.on(&quot;mousewheel&quot;, callback)</code>;</p>
        </td>
    </tr>
    <tr>
        <td><a href="http://yuilibrary.com/yui/docs/api/module_event-move.html"><code>event-move</code></a></td>
        <td>
            Adds <a href="touch.html#move">"gesturemovestart", "gesturemove",
            and "gesturemoveend" events</a> that serve as abstractions over
            mouse and touch events, forking internally based on the client
            device.
        </td>
    </tr>
    <tr>
        <td><a href="http://yuilibrary.com/yui/docs/api/module_event-outside.html"><code>event-outside</code></a></td>
        <td>
            Adds a <a href="outside.html">"clickoutside" and several other
            outside events</a> to trigger behavior based on actions taken
            outside a specific element.
        </td>
    </tr>
    <tr>
        <td><a href="http://yuilibrary.com/yui/docs/api/module_event-resize.html"><code>event-resize</code></a></td>
        <td>
            <p>Adds a "windowresize" event that only fires after a user has
            stopped dragging a window's resize handle.  This normalizes the
            <code>window.onresize</code> event across browsers.</p>

            <p>This event can only be subscribed with
            <code>Y.on(&quot;windowresize&quot;, callback)</code>;</p>
        </td>
    </tr>
    <tr>
        <td><a href="http://yuilibrary.com/yui/docs/api/module_event-touch.html"><code>event-touch</code></a></td>
        <td>
            Adds support for <a href="touch.html">subscribing to native touch
            and gesture events</a>.
        </td>
    </tr>
    <tr>
        <td><a href="http://yuilibrary.com/yui/docs/api/module_event-valuechange.html"><code>event-valuechange</code></a></td>
        <td>
            Adds a <a href="valuechange.html">"valueChange" event</a> that fires when input element text
            changes (this is harder than you think).
        </td>
    </tr>
</tbody>
</table>

<h2 id="delegation">Event Delegation</h2>

<p>If you don't already know what event delegation is, you should <a
href="delegation.html">read this quick overview</a>. Short form: <em>you need
to be using this</em>.</p>

<pre class="code prettyprint">&#x2F;&#x2F; single element subscription
node.on(&quot;click&quot;, handleClick);

&#x2F;&#x2F; delegated subscription for all button clicks from inside the node
node.delegate(&quot;click&quot;, handleClick, &quot;button, input[type=button]&quot;);</pre>


<p>Creating a delegated subscription looks very much like creating any other
event subscription with two differences. First, it's a different method name,
<code>delegate</code>.  Second, there is another argument: a CSS selector that is used to
test the event's originating element to decide if the callback should be
executed.  If the event started at or inside an element matching the selector,
the callback will execute.</p>

<p>Unlike <code>node.on()</code> subscriptions, the <code>this</code> object in <code>node.delegate()</code>
callbacks will refer to the element that matched the css filter, not to <code>node</code>.
We did this because likely your logic revolves around the nodes described by
the filter, not around the element that contains them.</p>

<pre class="code prettyprint">function handleClick (e) {
    &#x2F;&#x2F; &#x60;this&#x60; is the button with class .remove, not the #items element
    &#x2F;&#x2F; remove the containing LI
    this.ancestor(&#x27;li&#x27;).remove();

    &#x2F;&#x2F; e.currentTarget is also the button.remove
    &#x2F;&#x2F; e.container === Y.one(&#x27;#items&#x27;)
}

Y.one(&#x27;#items&#x27;).delegate(&#x27;click&#x27;, handleClick, &#x27;button.remove&#x27;);</pre>


<p>For more complex target filtering, a function can be passed instead of a css
selector.  See the
<a href="http://yuilibrary.com/yui/docs/api/module_event-delegate.html#method_delegate">API docs</a>
for more details.</p>

<p>As noted <a href="#modules">above</a>, the <code>event-delegate</code> module is
included in the <code>event</code> rollup, but <code>node-event-delegate</code> isn't.  We recommend
using delegation from the Node API, so you should <code>use()</code> either
<code>node-event-delegate</code> or the <code>node</code> rollup.</p>


<h2 id="more">More Event API Goodness</h2>

<p>
    Here is a sampling of some of the other ways to manage event subscriptions
    in YUI.
</p>

<h4 id="y-on">Subscribe from <code>Y</code></h4>

<pre class="code prettyprint">&#x2F;&#x2F; Y.on() takes a third argument which is the Node, DOM element,
&#x2F;&#x2F; or CSS selector of the element(s) to bind
Y.on(&quot;click&quot;, handleClick, &quot;#readygo&quot;);

&#x2F;&#x2F; Y.delegate() similarly takes the containing element or selector
&#x2F;&#x2F; as the third argument
Y.delegate(&quot;click&quot;, handleClick, &quot;#container&quot;, &quot;button, input[type=button]&quot;);</pre>


<p>
    An alternate syntax for DOM subscriptions is using <code>Y.on()</code> or
    <code>Y.delegate()</code>.  When identifying the target by a CSS selector, these
    methods can be used regardless if the element is currently available for
    scripting.  If it's not yet on the page, a poll will regularly look for it
    (for a few seconds) and the subscription will be automatically attached
    when the element is found.  Relying on this behavior can introduce race
    conditions, though, so use it wisely.
</p>
<p>
    Use of <code>Y.on()</code> instead of <code>node.on()</code> is largely a stylistic preference,
    though <a href="#y-on-vs-node-on">there are some technical differences</a>.
</p>


<h4 id="once">One time subscriptions</h4>

<pre class="code prettyprint">tabLabel.once(&#x27;mouseover&#x27;, loadTabContent);</pre>


<p>If you only want to execute a callback on the first occurrence of an event, use <code>node.once()</code> or <code>Y.once()</code>.  The subscription will automatically be detached after the event fires.</p>

<p>The signature for <code>once()</code> is the same as <code>on()</code>.</p>

<h4 id="grouping-subscriptions">Grouping subscriptions</h4>

<p>Pass an object to subscribe to multiple events, each with their own
callback</p>

<pre class="code prettyprint">function validate(e) { ... }
function clearPlaceholder(e) { ... }

var groupSub = inputNode.on({
    blur    : validate,
    keypress: validate,
    focus   : clearPlaceholder
});

&#x2F;&#x2F; Detach the blur, keypress, and focus subscriptions in one call
groupSub.detach();</pre>


<p>Pass an array to subscribe to multiple events with the same callback</p>
<pre class="code prettyprint">function activate(e) { ... }

groupSub = inputNode.on([&#x27;focus&#x27;, &#x27;mouseover&#x27;], activate);

&#x2F;&#x2F; Detach the focus and mouseover subscriptions
groupSub.detach();</pre>


<p>Prefix the event name with a category to allow detaching multiple
subscriptions by that category.</p>

<pre class="code prettyprint">inputNode.on(&#x27;my-category|focus&#x27;, activate);
inputNode.on(&#x27;my-category|mouseover&#x27;, activate);

&#x2F;&#x2F; You can detach specific subscriptions by &#x27;my-category|focus&#x27; or all with |*
inputNode.detach(&#x27;my-category|*&#x27;);</pre>


<p>The <code>once()</code> and <code>delegate()</code> methods also support these alternate
signatures.</p>

<h4 id="extended-signature">Binding <code>this</code> and additional callback arguments</h4>

<p>
    By default, the "<code>this</code>" object in subscription callbacks will be the Node
    or NodeList that subscribed to them.  Override this default by passing your
    own <code>this</code> object as the third argument to <code>on()</code> or the fourth to
    <code>delegate()</code>.  Note that the argument index is shifted when using <code>Y.on()</code>
    and <code>Y.delegate()</code> or <a href="synths.html">synthetic events with custom
    signatures</a>.
</p>

<pre class="code prettyprint">&#x2F;&#x2F; equivalent to node.on(&#x27;click&#x27;, function (e) { overlay.hide(e); });
node.on(&#x27;click&#x27;, overlay.show, overlay);

node.once(&#x27;mouseover&#x27;, door.unlock, door);

&#x2F;&#x2F; &#x60;this&#x60; override comes after the filter; also shifted for the &#x27;key&#x27; event&#x27;s
&#x2F;&#x2F; custome signature.
container.delegate(&#x27;key&#x27;, validator.isValid, &#x27;enter,tab&#x27;, &#x27;input&#x27;, validator);

&#x2F;&#x2F; Corresponding alternatives from Y
Y.on(&#x27;click&#x27;, overlay.show, &#x27;#show&#x27;, overlay);

Y.once(&#x27;mouseover&#x27;, door.unlock, &#x27;#gate13&#x27;, door);

Y.delegate(&#x27;key&#x27;, validator.isValid, &#x27;#myForm&#x27;, &#x27;enter,tab&#x27;, &#x27;input&#x27;, validator);</pre>


<p>Additional arguments passed to the subscription methods will be sent along
to the callback after the event facade. If you want to bind extra arguments,
but don't want to override the "<code>this</code>" object, pass <code>null</code> for the <code>this</code>
argument.</p>

<pre class="code prettyprint">MyClass.prototype = {
    someMethod: function (param) {
        Y.log(param); &#x2F;&#x2F; =&gt; &quot;I&#x27;m Extra!&quot;
    },

    handleClick: function (e, extraParam) {
        this.someMethod(extraParam);
        ...
    },
    ...
};

var instance = new Y.MyClass();

&#x2F;&#x2F; The extra arg is passed as the second param to the callback after &#x60;e&#x60;
Y.one(&#x27;#readygo&#x27;).on(&#x27;click&#x27;, instance.handleClick, instance, &quot;I&#x27;m Extra!&quot;);</pre>


<h4 id="detach-methods">More ways to clean up subscriptions</h4>

<p>There are a lot of options for detaching events in YUI.  See the table below for details.</p>

<table>
<thead>
    <tr>
        <th>Method</th>
        <th>What it does</th>
    </tr>
</thead>
<tbody>
    <tr>
        <td>
<pre class="code prettyprint">var subscription = node.on(&#x27;click&#x27;, callback);

subscription.detach();</pre>

        </td>
        <td>
            <p>
                Removes a specific subscription or, if created with one of the
                group subscription methods, a group of subscriptions.
            </p>
            <p>
                Generally, this is the best method to use.
            </p>
        </td>
    </tr>
    <tr id="remove-by-category">
        <td>
<pre class="code prettyprint">node.on(&#x27;foo-category|click&#x27;, callback);

node.detach(&#x27;foo-category|click&#x27;);
&#x2F;&#x2F; OR
node.detach(&#x27;foo-category|*&#x27;);</pre>

        </td>
        <td>
            <p>
                Removes a subscription or group of subscriptions that included
                the specified category in the subscription event type.
            </p>
            <p>
                This is typically only safe in implementation code, not
                module code, because multiple subscriptions using the same type
                and category will be detached by the call to <code>detach</code>.
            </p>
        </td>
    </tr>
    <tr>
        <td>
<pre class="code prettyprint">node.detach(&#x27;click&#x27;, callback);
&#x2F;&#x2F; OR
node.detach(&#x27;click&#x27;);
&#x2F;&#x2F; OR
node.detach():</pre>

        </td>
        <td>
            <p>
                If you have a reference to the subscribed callback function,
                (but not a subscription handle) use the two argument signature.
            </p>
            <p>
                With one argument, <code>detach</code> will remove all subscriptions for
                the specified event.  With no arguments, it removes all
                subscriptions for all events.
            </p>
            <p>
                <code>detach</code> does not remove subscriptions from descendant nodes.
            </p>
        </td>
    </tr>
    <tr>
        <td>
<pre class="code prettyprint">node.detachAll();</pre>

        </td>
        <td>
            <p>
                Works the same as <code>node.detach()</code>.
            </p>
        </td>
    </tr>
    <tr>
        <td>
<pre class="code prettyprint">node.purge();
&#x2F;&#x2F; OR
node.purge(true);
&#x2F;&#x2F; OR
node.purge(true, &#x27;click&#x27;);</pre>

        </td>
        <td>
            <p>
                With no arguments, <code>purge</code> works the same as <code>node.detach()</code>.
            </p>
            <p>
                Passing <code>true</code> as a first argument will remove all
                subscriptions for all events from the node <em>and its
                descendant subtree</em>. Passing an event type as a second
                argument will only deep purge subscriptions to that event.
            </p>
        </td>
    </tr>
    <tr>
        <td>
<pre class="code prettyprint">node.empty();</pre>

        </td>
        <td>
            <p>
                Removes subscriptions for all events <em>only from the
                descendants of a node</em> after removing them from the DOM.
            </p>
        </td>
    </tr>
    <tr>
        <td>
<pre class="code prettyprint">node.destroy();
&#x2F;&#x2F; OR
node.destroy(true);</pre>

        </td>
        <td>
            <p>
                With no arguments, works like <code>node.detach()</code>.
            </p>
            <p>
                With <code>true</code> as a first argument, it works like
                <code>node.purge(true)</code>.
            </p>
            <p>
                The <code>destroy</code> method does more than detaching event
                subscribers.  Read the
                <a href="http://yuilibrary.com/yui/docs/api/classes/Node.html#method_destroy">API
                docs</a> for details.
            </p>
        </td>
    </tr>
    <tr>
        <td>
<pre class="code prettyprint">Y.Event.detach(&#x27;click&#x27;, callback, &#x27;#foo&#x27;);</pre>

        </td>
        <td>
            <p>
                Same as <code>Y.one(&#x27;#foo&#x27;).detach( [other args] )</code>.
            </p>
        </td>
    </tr>
    <tr>
        <td>
<pre class="code prettyprint">Y.Event.purgeElement(&#x27;#foo&#x27;, true, &#x27;click&#x27;);</pre>

        </td>
        <td>
            <p>
                Same as <code>Y.one(&#x27;#foo&#x27;).purge( [other args] )</code>.
            </p>
        </td>
    </tr>
</tbody>
</table>

<h2 id="simulate">Simulate browser events</h2>

<p>
    For creating automated functional tests, being able to simulate user
    interaction can be crucial.  That's where the <code>node-event-simulate</code> module
    comes in.
</p>

<pre class="code prettyprint">YUI().use(&#x27;test&#x27;, &#x27;node-event-simulate&#x27;, &#x27;fancy&#x27;, function (Y) {

var test = new Y.Test.Case({
    ...

    &quot;clicking close button should dismiss UI&quot;: function () {

        var widget      = new Y.MyFancyWidget().render(&#x27;#here&#x27;),
            uiBox       = widget.get(&#x27;boundingBox&#x27;),
            closeButton = uiBox.one(&#x27;.close-button&#x27;);

        closeButton.simulate(&#x27;click&#x27;);

        Y.Assert.isFalse( uiBox.inDoc() );
    },
    ...</pre>


<p>
    <code>node.simulate( type, eventProperties )</code> creates a native DOM event that
    will bubble (if appropriate), but will not trigger native default behavior.
    For example, <code>node.simulate(&#x27;submit&#x27;)</code> will not send data to the server for
    a page reload.
</p>

<p>Read <a href="simulate.html">more about event simulation here</a>.</p>

<h2 id="synthetic-events">Synthetic Events</h2>

<p>The event system supports adding new abstractions over the native DOM
environment that behave like DOM events.  These abstractions are called
synthetic events, and you can subscribe to them like any other DOM event with
<code>node.on()</code> or <code>node.delegate()</code>.</p>

<pre class="code prettyprint">Y.one(&#x27;#dialog&#x27;).on(&#x27;clickoutside&#x27;, function (e) {
    this.transition(&#x27;fadeOut&#x27;);
});

Y.one(&#x27;#editable-table&#x27;).delegate(&#x27;key&#x27;, saveAndAdvance, &#x27;tab&#x27;, &#x27;input&#x27;);</pre>


<p>
    The synthetic events that are available as core YUI modules are listed in
    <a href="#modules">the table of modules above</a>, though there are others
    <a href="http://yuilibrary.com/gallery/">in the Gallery</a>.  Most events
    listed in the table are linked to pages that describe the specific event in
    more detail.
</p>

<h4 id="creating-dom-events">Creating DOM events</h4>

<p>Create your own synthetic events with <code>Y.Event.define(type, config)</code>.</p>

<pre class="code prettyprint">Y.Event.define(&quot;tripleclick&quot;, {

    &#x2F;&#x2F; The setup logic executed when node.on(&#x27;tripleclick&#x27;, callback) is called
    on: function (node, subscription, notifier) {
        &#x2F;&#x2F; supporting methods can be referenced from &#x60;this&#x60;
        this._clear(subscription);

        &#x2F;&#x2F; To make detaching easy, a common pattern is to add the subscription
        &#x2F;&#x2F; for the supporting DOM event to the subscription object passed in.
        &#x2F;&#x2F; This is then referenced in the detach() method below.
        subscription._handle = node.on(&#x27;click&#x27;, function (e) {
            if (subscription._timer) {
                subscription._timer.cancel();
            }

            if (++subscription._counter === 3) {
                this._clear(subscription);

                &#x2F;&#x2F; The notifier triggers the subscriptions to be executed.
                &#x2F;&#x2F; Pass its fire() method the triggering DOM event facade
                notifier.fire(e);
            } else {
                subscription._timer =
                    Y.later(300, this, this._clear, [subscription]);
            }
        });
    },

    &#x2F;&#x2F; The logic executed when the &#x27;tripleclick&#x27; subscription is &#x60;detach()&#x60;ed
    detach: function (node, subscription, notifier) {
        &#x2F;&#x2F; Clean up supporting DOM subscriptions and other external hooks
        &#x2F;&#x2F; when the synthetic event subscription is detached.
        subscription._handle.detach();

        if (subscription._timer) {
            subscription._timer.cancel();
        }
    },

    &#x2F;&#x2F; Additional methods can be added to support the lifecycle methods
    _clear: function (subscription) {
        subscription._counter = 0;
        subscription._timer = null;
    },
    
    ...
});</pre>


<p>After the synthetic event is defined, it is available for every Node and
NodeList to subscribe to.</p>

<pre class="code prettyprint">Y.one(&#x27;#hellokitty&#x27;).on(&#x27;tripleclick&#x27;, omgYayCantClickEnough);</pre>


<p>There is additional configuration to <a href="synths.html">add support for
<code>delegate()</code> or extra subscription arguments</a>, but often very little extra
code is needed.</p>

<h2 id="troubleshootingfaq">Troubleshooting/FAQ</h2>

<ul>
    <li><a href="#function-reference">My callback is executing at the wrong time. What's going on?</a></li>
    <li><a href="#wrong-this">I'm getting an error in my callback that "(some object) has no method (someMethodOnMyObject)". What am I missing?</a></li>
    <li><a href="#which-events">What events can I subscribe to?</a></li>
    <li><a href="#why-on-no-chain">Why isn't on() chainable?</a></li>
    <li><a href="#y-on-vs-node-on">Why would I use <code>Y.on()</code> or <code>Y.delegate()</code> instead of <code>node.on()</code> and <code>node.delegate()</code>?</a></li>
    <li><a href="#after">EventTarget also provides an <code>after()</code> method. How does that work for DOM events?</a></li>
    <li><a href="#nodelist-this">When I subscribe to an event from a NodeList, <code>this</code> is the NodeList, not the individual Node.  What's up with that?</a></li>
    <li><a href="#nodelist-delegate">Where is <code>nodelist.delegate()</code>?</a></li>
    <!--li><a href="#">What works and what doesn't on mobile browsers?</a></li-->
</ul>

<h4 id="function-reference">My callback is executing at the wrong time. What's going on?</h4>

<p>It's likely that you've included parenthese in the subscription.</p>
<pre class="code prettyprint">&#x2F;&#x2F; WRONG
node.on(&#x27;click&#x27;, someFunction());
node.on(&#x27;click&#x27;, myObject.someFunction());

&#x2F;&#x2F; RIGHT
node.on(&#x27;click&#x27;, someFunction);
node.on(&#x27;click&#x27;, myObject.someFunction, myObject);</pre>


<p>
    Including the parens makes the function execute immediately, and pass the
    return value from the function to <code>node.on(&#x27;click&#x27;, [RETURN VALUE])</code>.  To
    pass a function around, just omit the parens.
</p>

<h4 id="wrong-this">I'm getting an error in my callback that "<code>(some object) has no method (someMethodOnMyObject)</code>". What am I missing?</h4>

<p>
    You may be passing an object method to <code>on()</code>, but forgot to include
    <a href="#extended-signature">the <code>this</code> object override parameter</a> in
    the subscription.
</p>

<p>
    Another option to make sure object methods are called with the correct
    <code>this</code> object is to use
    <a href="http://yuilibrary.com/yui/docs/api/classes/YUI.html#method_bind">`Y.bind(obj.method,
    obj)`</a> or
    <a href="http://yuilibrary.com/yui/docs/api/classes/YUI.html#method_rbind">`Y.rbind(obj.method,
    obj)`</a>.
</p>

<pre class="code prettyprint">&#x2F;&#x2F; WRONG
node.on(&#x27;click&#x27;, myObj.method);

&#x2F;&#x2F; RIGHT
node.on(&#x27;click&#x27;, myObj.method, myObj);

&#x2F;&#x2F; RIGHT (alternate)
node.on(&#x27;click&#x27;, Y.rbind(obj.method, obj));</pre>


<h4 id="which-events">What events can I subscribe to?</h4>

<p>
    It depends what modules you've included.  Check out the
    <a href="#event-whitelist">whitelisted events table</a>.
</p>

<h4 id="why-on-no-chain">Why isn't on() chainable?</h4>

<p>
    After much deliberation, the YUI team decided that returning a subscription
    handle was preferable to chaining in order to better support clean event
    detaching across the various scenarios that DOM and custom events are used.
</p>
<p>
    In any sizable application, managing event subscriptions becomes
    increasingly important, and detaching events must be done with precision.
    Because YUI allows duplicate subscriptions, any host-based detach method
    will necessarily be less than 100% reliable with respect to avoiding
    removal of subscriptions made by other parts of the system.
</p>
<p>
    Otherwise, it's common to subscribe to events with anonymous functions,
    which makes it impossible to detach the specific subscription by signature
    because you don't have a function reference to use to identify the specific
    subscription to remove.  Subscription categories can be used, but
    <a href="#remove-by-category">are also less precise</a> than
    dealing with a specific subscription object.
</p>

<h4 id="y-on-vs-node-on">Why would I use <code>Y.on()</code> or <code>Y.delegate()</code> instead of <code>node.on()</code> and <code>node.delegate()</code>?</h4>

<p>
    It's <a href="#y-on">largely a stylistic preference</a>, but there are some
    technical differences when passing a selector string as a the third
    argument to <code>Y.on()</code> or <code>Y.delegate()</code> (ala
    <code>Y.on(&#x27;click&#x27;, callback, &#x27;#some select.or-string&#x27;)</code>.
</p>

<ol>
    <li>
        <p>
            <code>Y.on()</code> uses the
            <a href="http://yuilibrary.com/yui/docs/api/classes/Selector.html">Selector engine</a>
            directly rather than calling through <code>Y.all(...)</code>.
        </p>
        <p>
            The benefit here is that the Node and NodeList constructors add the
            slightest bit of overhead to the subscription process.
        </p>
    </li>
    <li>
        When passing a selector that matches multiple elements, the <code>this</code> in
        the callback will be the individual Node, not a
        <a href="#nodelist-this">NodeList wrapping all matched elements</a>.
    </li>
    <li>
        <p>
            If called before the elements matching the selector are attached to
            the DOM, it will poll for a few seconds and automatically attach
            the subscription when the first matching element is found.
        </p>
        <p>
            Note, if using a selector that matches multiple elements, the poll
            will attach the subscription the first time Selector finds a match.
            This <em>may not include all the elements</em> because either the
            DOM is not fully updated yet, or the code that adds the matching
            elements may happen in batches.
        </p>
        <p>In practice, it is best to avoid reliance on this behavior.</p>
    </li>
</ol>

<h4 id="after"><code>EventTarget</code> also provides an <code>after()</code> method. How does that work for DOM events?</h4>

<p>
    <code>node.after(...)</code> is equivalent to <code>node.on(...)</code>.  The DOM doesn't expose
    an "after" moment to hook into.
</p>

<h4 id="nodelist-this">When I subscribe to an event from a NodeList, <code>this</code> is the NodeList, not the individual Node.  What's up with that?</h4>

<p>
    In the callback, <code>e.currentTarget</code> will always refer to the individual Node.
    However, if you call
</p>

<pre class="code prettyprint">Y.all(&#x27;#some select.or-string&#x27;).on(&#x27;click&#x27;, function (e) {
    &#x2F;&#x2F; how do I reference the NodeList?
});</pre>


<p>
    you can't reference the NodeList captured by <code>Y.all()</code> without calling
    <code>Y.all()</code> again, but that results in unnecessary overhead, and may match
    different elements in the subsequent call.
</p>

<p>
    In general, you should avoid <code>nodelist.on()</code> anyway,
    <a href="#delegation">in favor of event delegation</a>.
</p>

<h4 id="nodelist-delegate">Where is <code>nodelist.delegate()</code>?</h4>

<p>
    The point of delegation is to reduce the number of subscriptions being made.
    <code>nodelist.delegate()</code> would be philosophically at odds with that. Either
    call <code>node.delegate()</code> from an element higher up the DOM tree, or <em>if
    you must</em> delegate the same event and callback from multiple
    containers, use
</p>

<pre class="code prettyprint">nodelist.each(function (node) {
    node.delegate(&#x27;click&#x27;, callback, &#x27;.not-recommended&#x27;);
});</pre>


<h2 id="event-whitelist">Appendix A: Whitelisted DOM events</h2>

<div id="events">
<table>
<thead>
    <tr>
        <th>Event</th>
        <th>Added by</th>
    </tr>
</thead>
<tbody>
    <tr>
        <td>abort</td>
        <td>node-base</td>
    </tr>
    <tr>
        <td>beforeunload</td>
        <td>node-base</td>
    </tr>
    <tr>
        <td>blur</td>
        <td>node-base</td>
    </tr>
    <tr>
        <td>change</td>
        <td>node-base</td>
    </tr>
    <tr>
        <td>click</td>
        <td>node-base</td>
    </tr>
    <tr>
        <td>close</td>
        <td>node-base</td>
    </tr>
    <tr>
        <td>command</td>
        <td>node-base</td>
    </tr>
    <tr>
        <td>contextmenu</td>
        <td>node-base</td>
    </tr>
    <tr>
        <td>dblclick</td>
        <td>node-base</td>
    </tr>
    <tr>
        <td>DOMMouseScroll</td>
        <td>node-base</td>
    </tr>
    <tr>
        <td>drag</td>
        <td>node-base</td>
    </tr>
    <tr>
        <td>dragstart</td>
        <td>node-base</td>
    </tr>
    <tr>
        <td>dragenter</td>
        <td>node-base</td>
    </tr>
    <tr>
        <td>dragover</td>
        <td>node-base</td>
    </tr>
    <tr>
        <td>dragleave</td>
        <td>node-base</td>
    </tr>
    <tr>
        <td>dragend</td>
        <td>node-base</td>
    </tr>
    <tr>
        <td>drop</td>
        <td>node-base</td>
    </tr>
    <tr>
        <td>error</td>
        <td>node-base</td>
    </tr>
    <tr>
        <td>focus</td>
        <td>node-base</td>
    </tr>
    <tr>
        <td>key</td>
        <td>node-base</td>
    </tr>
    <tr>
        <td>keydown</td>
        <td>node-base</td>
    </tr>
    <tr>
        <td>keypress</td>
        <td>node-base</td>
    </tr>
    <tr>
        <td>keyup</td>
        <td>node-base</td>
    </tr>
    <tr>
        <td>load</td>
        <td>node-base</td>
    </tr>
    <tr>
        <td>message</td>
        <td>node-base</td>
    </tr>
    <tr>
        <td>mousedown</td>
        <td>node-base</td>
    </tr>
    <tr>
        <td>mouseenter</td>
        <td>node-base</td>
    </tr>
    <tr>
        <td>mouseleave</td>
        <td>node-base</td>
    </tr>
    <tr>
        <td>mousemove</td>
        <td>node-base</td>
    </tr>
    <tr>
        <td>mousemultiwheel</td>
        <td>node-base</td>
    </tr>
    <tr>
        <td>mouseout</td>
        <td>node-base</td>
    </tr>
    <tr>
        <td>mouseover</td>
        <td>node-base</td>
    </tr>
    <tr>
        <td>mouseup</td>
        <td>node-base</td>
    </tr>
    <tr>
        <td>mousewheel</td>
        <td>node-base</td>
    </tr>
    <tr>
        <td>orientationchange</td>
        <td>node-base</td>
    </tr>
    <tr>
        <td>reset</td>
        <td>node-base</td>
    </tr>
    <tr>
        <td>resize</td>
        <td>node-base</td>
    </tr>
    <tr>
        <td>select</td>
        <td>node-base</td>
    </tr>
    <tr>
        <td>selectstart</td>
        <td>node-base</td>
    </tr>
    <tr>
        <td>submit</td>
        <td>node-base</td>
    </tr>
    <tr>
        <td>scroll</td>
        <td>node-base</td>
    </tr>
    <tr>
        <td>textInput</td>
        <td>node-base</td>
    </tr>
    <tr>
        <td>unload</td>
        <td>node-base</td>
    </tr>

    <tr>
        <td>DOMActivate</td>
        <td>node-event-html5</td>
    </tr>
    <tr>
        <td>DOMContentLoaded</td>
        <td>node-event-html5</td>
    </tr>
    <tr>
        <td>afterprint</td>
        <td>node-event-html5</td>
    </tr>
    <tr>
        <td>beforeprint</td>
        <td>node-event-html5</td>
    </tr>
    <tr>
        <td>canplay</td>
        <td>node-event-html5</td>
    </tr>
    <tr>
        <td>canplaythrough</td>
        <td>node-event-html5</td>
    </tr>
    <tr>
        <td>durationchange</td>
        <td>node-event-html5</td>
    </tr>
    <tr>
        <td>emptied</td>
        <td>node-event-html5</td>
    </tr>
    <tr>
        <td>ended</td>
        <td>node-event-html5</td>
    </tr>
    <tr>
        <td>formchange</td>
        <td>node-event-html5</td>
    </tr>
    <tr>
        <td>forminput</td>
        <td>node-event-html5</td>
    </tr>
    <tr>
        <td>hashchange</td>
        <td>node-event-html5</td>
    </tr>
    <tr>
        <td>input</td>
        <td>node-event-html5</td>
    </tr>
    <tr>
        <td>invalid</td>
        <td>node-event-html5</td>
    </tr>
    <tr>
        <td>loadedmetadata</td>
        <td>node-event-html5</td>
    </tr>
    <tr>
        <td>loadeddata</td>
        <td>node-event-html5</td>
    </tr>
    <tr>
        <td>loadstart</td>
        <td>node-event-html5</td>
    </tr>
    <tr>
        <td>offline</td>
        <td>node-event-html5</td>
    </tr>
    <tr>
        <td>online</td>
        <td>node-event-html5</td>
    </tr>
    <tr>
        <td>pagehide</td>
        <td>node-event-html5</td>
    </tr>
    <tr>
        <td>pageshow</td>
        <td>node-event-html5</td>
    </tr>
    <tr>
        <td>pause</td>
        <td>node-event-html5</td>
    </tr>
    <tr>
        <td>play</td>
        <td>node-event-html5</td>
    </tr>
    <tr>
        <td>playing</td>
        <td>node-event-html5</td>
    </tr>
    <tr>
        <td>popstate</td>
        <td>node-event-html5 or history</td>
    </tr>
    <tr>
        <td>progress</td>
        <td>node-event-html5</td>
    </tr>
    <tr>
        <td>ratechange</td>
        <td>node-event-html5</td>
    </tr>
    <tr>
        <td>readystatechange</td>
        <td>node-event-html5</td>
    </tr>
    <tr>
        <td>redo</td>
        <td>node-event-html5</td>
    </tr>
    <tr>
        <td>seeking</td>
        <td>node-event-html5</td>
    </tr>
    <tr>
        <td>seeked</td>
        <td>node-event-html5</td>
    </tr>
    <tr>
        <td>show</td>
        <td>node-event-html5</td>
    </tr>
    <tr>
        <td>stalled</td>
        <td>node-event-html5</td>
    </tr>
    <tr>
        <td>suspend</td>
        <td>node-event-html5</td>
    </tr>
    <tr>
        <td>timeupdate</td>
        <td>node-event-html5</td>
    </tr>
    <tr>
        <td>undo</td>
        <td>node-event-html5</td>
    </tr>
    <tr>
        <td>volumechange</td>
        <td>node-event-html5</td>
    </tr>
    <tr>
        <td>waiting</td>
        <td>node-event-html5</td>
    </tr>

    <tr>
        <td>touchstart</td>
        <td>event-touch</td>
    </tr>
    <tr>
        <td>touchmove</td>
        <td>event-touch</td>
    </tr>
    <tr>
        <td>touchend</td>
        <td>event-touch</td>
    </tr>
    <tr>
        <td>touchcancel</td>
        <td>event-touch</td>
    </tr>
    <tr>
        <td>gesturestart</td>
        <td>event-touch</td>
    </tr>
    <tr>
        <td>gesturechange</td>
        <td>event-touch</td>
    </tr>
    <tr>
        <td>gestureend</td>
        <td>event-touch</td>
    </tr>

    <tr>
        <td>transitionend or webkitTransitionEnd</td>
        <td>transition-native</td>
    </tr>
</tbody>
</table>
</div>
<script>
YUI({ filter: 'raw' }).use('selector-css3', 'datatable-sort', function (Y) {
    var data = [],
        node = Y.one('#events');

    node.all('td:nth-of-type(1)').each(function (node, i) {
        data.push({
            Event: node.get('text'),
            "Added By": node.next().get('text')
        });
    });

    node.empty().addClass('yui3-skin-sam');
    new Y.DataTable.Base({
        columnset: [
            { key: 'Event', sortable: true },
            { key: 'Added By', sortable: true }
        ],
        recordset: data
    }).plug(Y.Plugin.DataTableSort).render(node);

});
</script>

<h4 id="adding-to-the-dom-event-whitelist">Adding to the DOM event whitelist</h4>

<p>If you need to use an event that isn't included in this list, and not
supplied by a synthetic event, you can expand the whitelist by adding the event
names to the <code>Y.Node.DOM_EVENTS</code> object.</p>

<pre class="code prettyprint">&#x2F;&#x2F; Allow for subscription to some mostly cross-browser mutation events
Y.mix(Y.Node.DOM_EVENTS, {
    DOMNodeInserted: true,
    DOMNodeRemoved: true,
    DOMCharacterDataModified: true
});</pre>


<h2 id="facade-properties">Appendix B: EventFacade properties and methods</h2>

<h4 id="methods">Methods</h4>
<dl>
    <dt><code>e.preventDefault()</code></dt>
        <dd>
            Prevents the default action associated with the event. E.g. page
            navigation from an &lt;a&gt;nchor <code>click</code> or form submission and
            page reload from a %lt;form&gt; <code>submit</code>.
        </dd>
    <dt><code>e.stopPropagation()</code></dt>
        <dd>
            Stops the event from bubbling further up the DOM tree.  This does
            not prevent the default action if there is one.  Subsequent event
            subscribers will be executed.
        </dd>
    <dt><code>e.stopImmediatePropagation()</code></dt>
        <dd>
            Stops the event from bubbling further up the DOM tree.  This does
            not prevent the default action if there is one.  Subsequent event
            subscribers will NOT be executed.
        </dd>
    <dt><code>e.halt( [immediate=false] )</code></dt>
        <dd>
            Alias for <code>e.preventDefault(); e.stopPropagation();</code> or
            <code>e.preventDefault(); e.stopImmediatePropagation();</code>, depending on
            the <em>immediate</em> parameter.
        </dd>
</dl>

<h4 id="basics">Basics</h4>
<dl>
    <dt><code>e.type</code></dt>
        <dd>
            The name of the event. E.g. "click", "keyup", or "load".
        </dd>

    <dt><code>e.target</code></dt>
        <dd>
            The Node instance that originated the event (see <a
            href="delegation.html">the description of event delegation</a> for
            reference)
        </dd>
    <dt><code>e.currentTarget</code></dt>
        <dd>
            The Node instance that subscribed to the event. In the case of
            subscriptions from NodeLists, this is still the individual Node
            instance (see <a href="#nodelist-this">When I subscribe to an event
            from a NodeList, <code>this</code> is the NodeList...</a>).
        </dd>
    <dt><code>e.relatedTarget</code></dt>
        <dd>
            For <code>mouseover</code> events, this will be the Node instance of where the
            mouse travelled <em>from</em>.  For <code>mouseout</code>, it will be the Node
            that the mouse travelled <em>to</em>.
        </dd>
</dl>

<h4 id="keyboard-event-properties">Keyboard event properties</h4>
    <dt><code>e.keyCode</code></dt>
        <dd>
            The unicode value of a non-character key in a <code>keypress</code> event or
            any key in <code>keydown</code> or <code>keyup</code>.  See <a
            href="https://developer.mozilla.org/en/DOM/event.keyCode">event.keyCode
            on MDC</a>.
        </dd>
    <dt><code>e.charCode</code></dt>
        <dd>
            The Unicode value of a character key pressed during a keypress
            event.  See <a
            href="https://developer.mozilla.org/en/DOM/event.charCode">event.charCode
            on MDC</a>.
        </dd>
    <dt><code>e.shiftKey</code></dt>
        <dd>
            <code>true</code> if the shift key was depressed during a key event.
        </dd>
    <dt><code>e.ctrlKey</code></dt>
        <dd>
            <code>true</code> if the control key was depressed during a key event.
        </dd>
    <dt><code>e.altKey</code></dt>
        <dd>
            <code>true</code> if the alt/option key was depressed during a key event.
        </dd>
    <dt><code>e.metaKey</code></dt>
        <dd>
            <code>true</code> if the "Windows" key on PCs or command key on Macs was
            depressed during a key event.
        </dd>
</dl>

<h4 id="mouse-event-properties">Mouse event properties</h4>
    <dt><code>e.button</code></dt>
        <dd>
            For <code>mouseup</code> events (<em>NOT <code>click</code> events</em>), indicates
            which mouse button is pressed.<br>
            <code>1</code> = left click, <code>2</code> = middle click, <code>3</code> = right click.
        </dd>
    <dt><code>e.which</code></dt>
        <dd>
            Alias for e.button.
        </dd>

    <dt><code>e.pageX</code></dt>
        <dd>
            The horizontal coordinate of the event relative to whole document.
        </dd>
    <dt><code>e.pageY</code></dt>
        <dd>
            The vertical coordinate of the event relative to whole document.
        </dd>
    <dt><code>e.clientX</code></dt>
        <dd>
            The horizontal coordinate of the event relative to viewport,
            regardless of scrolling.
        </dd>
    <dt><code>e.clientY</code></dt>
        <dd>
            The vertical coordinate of the event relative to viewport,
            regardless of scrolling.
        </dd>

    <dt>[<code>e.wheelDelta</code>]</dt>
        <dd>
            For <code>mousewheel</code> or <code>DOMMouseScroll</code> events, the pixel distance of
            the scroll.
        </dd>
</dl>

<h4 id="touch-event-properties">Touch event properties</h4>
<dl>
    <dt>[<code>e.touches</code>]</dt>
        <dd>
            <p>
                An array of <code>Touch</code> objects, where each <code>Touch</code> object represents a finger 
                currently touching the surface (regardless of the target of the current event). 
                For example, if you have two fingers on the surface, this array would have two 
                <code>Touch</code> objects, one for each finger.
            </p>
            
            <p>
                The common set of properties currently on a <code>Touch</code> object, which can be 
                relied up across environments, are <code>target</code>, <code>clientX</code>, <code>clientY</code>, <code>pageX</code>, 
                <code>pageY</code>, <code>screenX</code>, <code>screenY</code> and <code>identifier</code>.
            </p>    
        </dd>
    <dt>[<code>e.targetTouches</code>]</dt>
        <dd>
            <p>
                An array of <code>Touch</code> objects for every point of contact that is touching the 
                surface, and started on the element that is the target of the current event.
            </p>
        </dd>
    <dt>[<code>e.changedTouches</code>]</dt>
        <dd>
            <p>
                An array of <code>Touch</code> objects representing all touches that changed in this event.
            </p>
                
            <p>
               This property is most useful in <code>touchEnd</code> events, to identify the set of touches 
               which were removed from the surface, which resulted in the firing of the event. 
            </p>
        </dd>
</dl>

<h4 id="gesture-event-properties-currently-ios-specific">Gesture event properties (currently iOS specific)</h4>
<p>These properties are unique to Webkit on iOS currently, and are provided on the event facade when listening for the iOS <code>gesturestart</code>, <code>gesturechange</code> and <code>gestureend</code> multi-touch events.</p>
<dl>
    <dt>[<code>e.scale</code>]</dt>
        <dd>
            See Apple's documentation for <a href="http://developer.apple.com/library/safari/documentation/UserExperience/Reference/GestureEventClassReference/GestureEvent/GestureEvent.html#//apple_ref/javascript/instp/GestureEvent/scale">scale</a>. 
        </dd>
    <dt>[<code>e.rotation</code>]</dt>
        <dd>
            See Apple's documentation for <a href="http://developer.apple.com/library/safari/documentation/UserExperience/Reference/GestureEventClassReference/GestureEvent/GestureEvent.html#//apple_ref/javascript/instp/GestureEvent/rotation">rotation</a>.
        </dd>
</dl>

<p>See the <a href="http://www.w3.org/TR/touch-events/">W3C Touch Events Specification</a>, derived from the Webkit model, for more details.</p>

<p>Synthetic events may add or modify event facade properties.  These should be included in the documentation for the specific synthetic event.</p>

<p>For more details, check out the <a
href="https://developer.mozilla.org/en/DOM/event#Properties">MDC
documentation</a>.</p>
</div>
        </div>

        <div id="sidebar" class="yui3-u">
            
                <div id="toc" class="sidebox">
                    <div class="hd">
                        <h2 class="no-toc">Table of Contents</h2>
                    </div>

                    <div class="bd">
                        <ul class="toc">
<li>
<a href="#getting-started">Getting Started</a>
</li>
<li>
<a href="#the-basics">The Basics</a>
<ul class="toc">
<li>
<a href="#listening-for-events">Listening for events</a>
</li>
<li>
<a href="#the-callback-and-the-event-object">The Callback and the Event Object</a>
</li>
<li>
<a href="#epreventdefault-and-estoppropagation"><code>e.preventDefault()</code> and <code>e.stopPropagation()</code></a>
</li>
<li>
<a href="#detaching-subscriptions">Detaching subscriptions</a>
</li>
</ul>
</li>
<li>
<a href="#modules">What to <code>use()</code></a>
</li>
<li>
<a href="#delegation">Event Delegation</a>
</li>
<li>
<a href="#more">More Event API Goodness</a>
<ul class="toc">
<li>
<a href="#y-on">Subscribe from <code>Y</code></a>
</li>
<li>
<a href="#once">One time subscriptions</a>
</li>
<li>
<a href="#grouping-subscriptions">Grouping subscriptions</a>
</li>
<li>
<a href="#extended-signature">Binding <code>this</code> and additional callback arguments</a>
</li>
<li>
<a href="#detach-methods">More ways to clean up subscriptions</a>
</li>
</ul>
</li>
<li>
<a href="#simulate">Simulate browser events</a>
</li>
<li>
<a href="#synthetic-events">Synthetic Events</a>
<ul class="toc">
<li>
<a href="#creating-dom-events">Creating DOM events</a>
</li>
</ul>
</li>
<li>
<a href="#troubleshootingfaq">Troubleshooting/FAQ</a>
<ul class="toc">
<li>
<a href="#function-reference">My callback is executing at the wrong time. What's going on?</a>
</li>
<li>
<a href="#wrong-this">I'm getting an error in my callback that "<code>(some object) has no method (someMethodOnMyObject)</code>". What am I missing?</a>
</li>
<li>
<a href="#which-events">What events can I subscribe to?</a>
</li>
<li>
<a href="#why-on-no-chain">Why isn't on() chainable?</a>
</li>
<li>
<a href="#y-on-vs-node-on">Why would I use <code>Y.on()</code> or <code>Y.delegate()</code> instead of <code>node.on()</code> and <code>node.delegate()</code>?</a>
</li>
<li>
<a href="#after"><code>EventTarget</code> also provides an <code>after()</code> method. How does that work for DOM events?</a>
</li>
<li>
<a href="#nodelist-this">When I subscribe to an event from a NodeList, <code>this</code> is the NodeList, not the individual Node.  What's up with that?</a>
</li>
<li>
<a href="#nodelist-delegate">Where is <code>nodelist.delegate()</code>?</a>
</li>
</ul>
</li>
<li>
<a href="#event-whitelist">Appendix A: Whitelisted DOM events</a>
<ul class="toc">
<li>
<a href="#adding-to-the-dom-event-whitelist">Adding to the DOM event whitelist</a>
</li>
</ul>
</li>
<li>
<a href="#facade-properties">Appendix B: EventFacade properties and methods</a>
<ul class="toc">
<li>
<a href="#methods">Methods</a>
</li>
<li>
<a href="#basics">Basics</a>
</li>
<li>
<a href="#keyboard-event-properties">Keyboard event properties</a>
</li>
<li>
<a href="#mouse-event-properties">Mouse event properties</a>
</li>
<li>
<a href="#touch-event-properties">Touch event properties</a>
</li>
<li>
<a href="#gesture-event-properties-currently-ios-specific">Gesture event properties (currently iOS specific)</a>
</li>
</ul>
</li>
</ul>
                    </div>
                </div>
            

            
                <div class="sidebox">
                    <div class="hd">
                        <h2 class="no-toc">Examples</h2>
                    </div>

                    <div class="bd">
                        <ul class="examples">
                            
                                
                                    <li data-description="Use the Event Utility to attach simple DOM event handlers.">
                                        <a href="basic-example.html">Simple DOM Events</a>
                                    </li>
                                
                            
                                
                                    <li data-description="Using the synthetic event API to create a DOM event that fires in response to arrow keys being pressed.">
                                        <a href="synth-example.html">Creating an Arrow Event for DOM Subscription</a>
                                    </li>
                                
                            
                                
                                    <li data-description="Supporting cross-device swipe gestures, using the event-move gesture events">
                                        <a href="swipe-example.html">Supporting A Swipe Left Gesture</a>
                                    </li>
                                
                            
                                
                            
                                
                            
                                
                            
                                
                            
                                
                            
                        </ul>
                    </div>
                </div>
            

            
                <div class="sidebox">
                    <div class="hd">
                        <h2 class="no-toc">Examples That Use This Component</h2>
                    </div>

                    <div class="bd">
                        <ul class="examples">
                            
                                
                            
                                
                            
                                
                            
                                
                                    <li data-description="Shows how to extend the base widget class, to create your own Widgets.">
                                        <a href="../widget/widget-extend.html">Extending the Base Widget Class</a>
                                    </li>
                                
                            
                                
                                    <li data-description="Creating an accessible menu button using the Focus Manager Node Plugin, Event&#x27;s delegation support and mouseenter event, along with the Overlay widget and Node&#x27;s support for the WAI-ARIA Roles and States.">
                                        <a href="../node-focusmanager/node-focusmanager-3.html">Accessible Menu Button</a>
                                    </li>
                                
                            
                                
                                    <li data-description="Use IO to request data over HTTP.">
                                        <a href="../io/get.html">HTTP GET to request data</a>
                                    </li>
                                
                            
                                
                                    <li data-description="Example Photo Browser application.">
                                        <a href="../dd/photo-browser.html">Photo Browser</a>
                                    </li>
                                
                            
                                
                                    <li data-description="Portal style example using Drag &amp; Drop Event Bubbling and Animation.">
                                        <a href="../dd/portal-drag.html">Portal Style Example</a>
                                    </li>
                                
                            
                        </ul>
                    </div>
                </div>
            
        </div>
    </div>
</div>

<script src="../assets/vendor/prettify/prettify-min.js"></script>
<script>prettyPrint();</script>

</body>
</html>
